import React, { useState, useEffect } from 'react';
import { Upload, Modal, message } from 'antd';
import { PlusOutlined } from '@ant-design/icons';

function getBase64(file: any) {
    return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.readAsDataURL(file);
        reader.onload = () => resolve(reader.result);
        reader.onerror = error => reject(error);
    });
}

interface UploadFileType {
    bmp: string,
    jpg: string,
    png: string,
    gif: string,
    jpeg: string,
}

export const fileType: UploadFileType = {
    bmp: '.bmp',
    jpg: '.jpg',
    png: '.png',
    gif: '.gif',
    jpeg: 'jpeg'
}

interface Props {
    /**是否禁用上传功能 */
    disabled?: boolean

    /**需要上传图片的数量 */
    number?: Number

    /**组件获得的默认值 */
    value?: any

    /**用于触发表单值的更新 */
    onChange?: Function

    /**自定义处理上传的返回数据 */
    handleResponse?: Function

    /**上传的请求地址 */
    url?: string

    /**可上传的图片类型 */
    uploadFileType?: string | string[]
}

const ImageUpload: React.FC<Props> = ({
    number: uploadNumber = 1,
    disabled,
    value,
    onChange,
    handleResponse,
    url,
    uploadFileType
}) => {
    console.debug('ImageUpload value', value);
    const [fileList, setFileList] = useState<any>([]);
    const [previewImage, setPreviewImage] = useState('');
    const [previewTitle, setPreviewTitle] = useState('');
    const [previewVisible, setPreviewVisible] = useState(false);
    /**可上传的文件类型 '.bmp,.jpg,....' */
    const [accept, setAccept] = useState<string>();
    /**用于判断文件类型 ['bmp', 'jpg', ....] */
    const [acceptList, setAcceptList] = useState<string[]>([]);

    useEffect(() => {
        if (value) {
            const showList: any = [];
            if (_.isArray(value)) {
                value.forEach((imgPath: string, index: number) => {
                    showList.push({ uid: `-${index}`, name: 'image.png', status: 'done', url: imgPath });
                })
            } else {
                showList.push({ uid: '-1', name: 'image.png', status: 'done', url: value });
            }
            setFileList(showList);
        }
    }, [value])

    useEffect(() => {
        let typeString = '.bmp,.jpg,.png,.gif,.jpeg';
        if (Array.isArray(uploadFileType)) {
            typeString = uploadFileType.toString();
        } else if (typeof uploadFileType === 'string') {
            typeString = uploadFileType;
        }
        setAccept(typeString);
        setAcceptList(typeString.replace(/\./g, '').split(','));
    }, [uploadFileType])

    function handleCancel() {
        setPreviewVisible(false);
    };

    async function handlePreview(file: any) {
        if (!file.url && !file.preview) {
            file.preview = await getBase64(file.originFileObj);
        }

        setPreviewImage(file.url || file.preview);
        setPreviewTitle(file.name || file.url.substring(file.url.lastIndexOf('/') + 1));
        setPreviewVisible(true);
    };

    function handleChange({ fileList }: any) {
        setFileList(fileList);
        /**获取上传成功的图片列表 */
        if (fileList.every(({ status }: any) => status === 'done')) {
            const uploadDoneList = fileList.filter(({ type, response, url }: any) => {
                if (response && response.code === '200') {
                    // 成功上传时进行文件类型判断
                    const isAccept = acceptList.some((item: any) => type.search(item) > -1);
                    if (!isAccept) message.warning(`请上传 ${accept} 类型文件`);
                    return isAccept;
                } else if (url) {
                    return true;
                } else {
                    return false;
                }
            });

            /**获取图片地址 */
            const fileDataList = uploadDoneList.map((item: any) => {
                if (item.url) {
                    return item.url;
                } else {
                    const data = item.response.data;
                    return handleResponse ? handleResponse(data) : data;
                }
            })
            onChange && onChange((uploadNumber > 1) ? fileDataList : fileDataList[0]);
        }
    };

    const uploadButton = (
        <div>
            <PlusOutlined />
            <div style={{ marginTop: 8 }}>Upload</div>
        </div>
    );

    return (
        <>
            <Upload
                accept={accept}
                action={url ? url : REACT_APP_UPLOAD_URL}
                listType="picture-card"
                fileList={fileList}
                onPreview={handlePreview}
                onChange={handleChange}
                disabled={disabled}
            >
                {fileList.length >= uploadNumber ? null : uploadButton}
            </Upload>
            <Modal
                visible={previewVisible}
                title={previewTitle}
                footer={null}
                onCancel={handleCancel}
            >
                <img alt="example" style={{ width: '100%' }} src={previewImage} />
            </Modal>
        </>
    );
}

export default ImageUpload